/*
 * @Author: Laputa
 * @Date: 2023-05-30 15:44:54
 * @LastEditors: Laputa
 * @LastEditTime: 2023-09-15 18:21:04
 * @Description:
 *
 * Copyright (c) 2023 by Levetop, All Rights Reserved.
 */

#include "LT168_Config.h"
#include "RGB.h"
#include "RTC.h"
#include "ADC.h"
#include "comp.h"
#include "QSPI.h"

#include "debug.h"
#include "levetop.h"
#include "function_drv.h"
#include "wav.h"
#include "pit.h"
#include "tp_rtp.h"
#include "tp_ctp.h"
#include "cache.h"
#include "lt168_clock.h"
#include "delay.h"
#include "uiEncoder.h"
#include "communicate_Uart.h"
#include "communicate_Modbus.h"
#include "communicate_IIC.h"
#include "communicate_HID_CDC.h"

//zyy----------------------------
#include "gesture.h"
#include "gif.h"
#include "analogClock.h"
#include "digitalClock.h"
#include "scrollText.h"
#include "uiCounter.h"
#include "varCounter.h"
#include "needle.h"
#include "gesture.h"
#include "button.h"
#include "curve.h"
#include "multiVarButton.h"
#include "popupBox.h"
#include "slideMenu.h"
#include "keyBoard.h"
#include "textNumber.h"
#include "sliderBar.h"
#include "circularTouch.h"
#include "varButton.h"
//--------------------------------

#include "Usb_cdc.h"
#include "usb.h"
#include "uart.h"
#include "iic.h"

#include "css_psram.h"
#include "lt168_qspi.h"


void W25QXX_Exit_QPI(qspi* t)
{
	*(volatile unsigned char*)(0x40010000+0x23) &= ~(1<<((((int)t - 0x60000000)>>28)+5));//Ӳ
		//----------------------- Flash ˳QPI -----------------------
		// Ϊ QPIֻд

		    Bit_Clear(t->SSIENR, QSPI_SSIENR_SSIC_EN_MASK);//رSSI
			t->CTRLR1 = 0x00;			  //NDF = 0;
			t->CTRLR0 = 0x00800407;       //QUAD ֻд 8bit
			t->SPICTRLR0 = 0x40000002;
			t->BAUDR = 8;
			Bit_Set(t->SSIENR, QSPI_SSIENR_SSIC_EN_MASK);

			t->DR = 0xFF;				//Exit QPI mode
			asm("nop");asm("nop");asm("nop");
			for (; QSPI_Get_Status(QSPI1, QSPI_Status_BUSY) == QSPI_STATUS_BUSY;) asm("nop"); /* wait qspix idle */
		//----------------------- Flash ˳QPI -----------------------
}

void Cache_Init(void)
{
	volatile UINT32 rdata = 0;
	CACHE->LMEM_ACRG = 0x00000000;
	CACHE->LMEM_CCR = 0x85000030;

	do
	{
		rdata = CACHE->LMEM_CCR;
	}while((rdata&0x80000000) == 0x80000000);

	CACHE->LMEM_ACRG = 0x0000000A;
	CACHE->LMEM_CCR |= 0x00000001;
}

void InitialChip(void)
{
	volatile  uint32_t timeout=3000;	// 3000ms
	uint32_t temp1,temp2,value,rtc_wclk_div;

	EIC->IER = 0;								//Disable All Interrupts
	WDT->WCR = 0x0;

	/*
	OPTION->U16_PVDC.PVDTEST = 1;
	OPTION->U16_PVDC.PVDTEST = 2;
	OPTION->U16_PVDC.PVDTEST = 3;
	OPTION->U16_PVDC.PVDC = 3;	//0--2.16V1--2.32V2--2.48V3--2.64V
	OPTION->U16_PVDC.PVDOE = 1;
	OPTION->U16_PVDC.PVDE = 1;
	OPTION->U16_PVDC.PVDRE = 1;
	OPTION->U16_PVDC.PVDTEST = 0;
	 */

	Clock_Init(200);
	Cache_Init();

#if _USE_PRINTF_
	LTPrintf_Init(SerialOutChar);   //Դַ
#endif
}

void EPORT0_Init(void)
{
	//ҽADC[7:0]лΪEPORT0[7:0]
	OPTION->ADCCDISR = 0x0;
	OPTION->ADCCDISR = 0x4000;
	OPTION->ADCCDISR = 0x8000;
	OPTION->ADCCDISR = 0xC000;
	OPTION->ADCCDISR = 0xC010;

	EPORT0->EPDDR |= 0x10; 	//
	EPORT0->EPDR |= 0x10; 	//1
	EPORT0->EPDR &=~0x10; 	//0
}

void CLK_RST_IO_Init(void)
{
	// CLK/INT1[0]
	OPTION->U16_CCR.CCRTEST = 1;
	OPTION->U16_CCR.CCRTEST = 2;
	OPTION->U16_CCR.CCRTEST = 3;
	OPTION->U16_CCR.CLKOUTDIS = 1; //GPIO

	EPORT1->EPDDR |= (1<<0);
	EPORT1->EPPUE |= (1<<0);
	EPORT1->EPDR |= (1<<0);  // ߵƽ

	// RST/INT1[6]
	OPTION->U16_CCR.CCRTEST = 1;
	OPTION->U16_CCR.CCRTEST = 2;
	OPTION->U16_CCR.CCRTEST = 3;
	OPTION->U16_CCR.RSTOUTDIS = 1; //GPIO

	EPORT1->EPDDR |= (1<<6);
	EPORT1->EPPUE |= (1<<6);
	EPORT1->EPDR |= (1<<6);
}

void Check_version(void)
{
	uint8_t showbuff[10];
	uint8_t font_size = 24;

	if(UI_version < 3000 || UI_version > 4000 )
	{
		LT_ReadFlash_UI(showbuff, 0x80 + 0x24, 7);
		LT268_TFT_DrawSquare_Fill(0,0,LCD_XSIZE_TFT-1,LCD_YSIZE_TFT-1,Blue2);
		LT268_TFT_ShowAscll(6,10,font_size,0,Red,White,(uint8_t*)"Firmware version warning");
		LT268_TFT_ShowAscll(6,50,font_size,0,Black,White,(uint8_t*)"MCU_Code version: V3.20");
		LT268_TFT_ShowAscll(6,90,font_size,0,Black,White,(uint8_t*)"UI_Editor-II version:  ");
		LT268_TFT_ShowAscll(6+265,90,font_size,0,Black,White,(uint8_t*)showbuff);
		LCD_BL_Init(249);
		WDT_FeedDog();
		DelayMS(2000);
		WDT_FeedDog();
	}
}

void Ckeck_Flash_ID(void)
{
	uint32_t ID;
	uint8_t temp;
	ID = LT_W25N01GV_ReadID();

	if ((ID >= 0xEFAA21  && ID <= 0xEFAA23)|| ID == 0xC891C8 || ID == 0xC892C8 || ID == 0xC895C8 || ID ==0xB1100)
	{
		W25N01GV_Init();
#if LT_BBM
		BadBlockreplacement();
#endif
		if(ID == 0xC891C8 || ID == 0xC892C8 || ID == 0xC895C8)
		{
			temp = LT_W25N01GV_ReadSR(0xB0U);
			temp |= 0x01U;
			LT_W25N01GV_Write_Enable();
			LT_W25N01GV_Write_SR(0xB0U, temp);
			LT_W25N01GV_Wait_Busy();
		}
		Flash_Type = 2;
	}
	else
	{
		Flash_Type = 0;
		W25QXX_Init();
	}
}

void touch_buzzer(void);
void touch_buzzer_close(void);
int main(void)
{
	uint16_t dx, dy, w_temp = 0, h_temp = 0;
	uint32_t psram_id = 0;
	qspi * test_qspi   = QSPI2;

	uint32_t printf_en=0;

	InitialChip();

	UART_Debug_Init(SCI1,115200);


//	EPORT0_Init();	//ʱ
//	CLK_RST_IO_Init();

	LT_definition_Init();
	Flash_STD_Init();  /* exSPIFlash initialization */

	Ckeck_Flash_ID();

	LT_ReadParam(); /* get ui info */
	//LCD_TFT_Init(); /* TFT init */

#if (UARTBUS_OPTION == 5)
#if Secondary_screen

	if(Check_UIHead() == 0)	//UI error
		ckeck_UI();
#endif
#endif

#if	!LT_QSPI_SCREEN
	RGB_Init();		//QSPI_Vincent
#endif

//	LCD_XSIZE_TFT=480;  LCD_YSIZE_TFT=320; LCD_BL_Init(249); disp_V_Gray();  while(1);  		//RGB display(TFT test)

	/* communication port*/
#if (UARTBUS_OPTION == 0 || UARTBUS_OPTION == 1 || UARTBUS_OPTION == 2)
	UartTFT_SCI_Init(COMuart, gBaudrate);
#elif (UARTBUS_OPTION == 3)
	I2C_Slave_TEST(0x36);
#elif (UARTBUS_OPTION == 4)
	SPI_BUS_Initialization();
#elif (UARTBUS_OPTION == 5)
	USB_HID_Init();
#elif (UARTBUS_OPTION == 6)
	USB_CDC_Init();
#endif
#if (UARTBUS_OPTION == 2)
	Get_ModBus_CMD_info();
#endif

	PIT1_Init();    /* pit init */
#if LT_Rtc_Enanbe
	LT_RtcInit();   /* RTC init */
#endif

#if	LT_QSPI_SCREEN
	LT268_TFT_FillColor(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,0x0000);
	QSPI_BUFF_START[0] = 0x00000000;
	QSPI_BUFF_START[1] = 0x01001001;
	QSPI_BUFF_START[2] = 0x00000000;
	QSPI_BUFF_START[3] = 0x00000000;
	PIT0_Init();				//Initials the PIT0 for frame ending
	PIT3_Init();				//Initials the PIT3 for porch ending
	TFT_QSPI_screen_init();		//Drive screen by QSPI single wire
	TFT_QSPI_Quad_Init();		//Switch QSPI quad wire
	QSPI1_QSPI2_Priority_Set();	//Set priority between QSPI1 and QSPI2
	PIT0_EN(1);					//Start QSPI2 output
#endif

#if (LT_TOUCH_FLAG == 1) /* touch init */
	LT_TpInit();
#elif (LT_TOUCH_FLAG == 2)
	CTP_Init();
#endif

#if LT_PSRAM
     CSS_PSRAM_Init(test_qspi,ccs_sck_dv);
	 CSS_PSRAM_Enter_QPI(test_qspi);
#endif
	 Check_version();/* ui version */

	if (Start_page >= addr_index[7]) /* display UI start page */
		   Display_page(0);
	else   Display_page(Start_page);

	DelayMS(60);

	LCD_BL_Init(gDutyBuf[var[VAR_BL * 2 + 1]]); /* backlight */

#if LT_TOUCH_BUZZER /* touch buzzer */
	if (buzzer == 1)   touch_buzzer_init();
#endif

#if LT_ENCODER /* encoder */
	Encoder_Init();
#endif

#if LT_SD_UPDATE /* SDcard */
	SD_IN_Enable();
	SD_ud_flag = SD_detection();
#endif

	WDT_Init();

	while (1)
	{
		WDT_FeedDog();
#if (UARTBUS_OPTION == 0 || UARTBUS_OPTION == 4)
		Main_From_UartRxBuff();
		if (gUsartRx.Flag)	LT_ReceiveCmd(gUsartRx.Buf);
		if(UI_update == 1)
		{
			while(1)
			{
				WDT_FeedDog();
				Main_From_UartRxBuff();
				if (gUsartRx.Flag)	LT_ReceiveCmd(gUsartRx.Buf);
				if (UI_update == 0)	break;
			}
		}

#elif (UARTBUS_OPTION == 1)
		LT_ModBus_REG_Cmd();
#elif (UARTBUS_OPTION == 2)
		if (Sum_ModbusTX)	Uart_cmd_Send();
		LT_ModBus_REG_Cmd();
#elif (UARTBUS_OPTION == 3)
		LT_IIC_REG_Cmd(); // handle instruction function of writing register
#elif (UARTBUS_OPTION == 5 || UARTBUS_OPTION == 6)

		Hid_Main_From_UartRxBuff();
		if (gHidRx.Flag)	LT_Hid_ReceiveCmd(gHidRx.Buf);
		if (UI_update == 1)
		{
			while(1)
			{
				WDT_FeedDog();
				Hid_Main_From_UartRxBuff();
				if (gHidRx.Flag)	LT_Hid_ReceiveCmd(gHidRx.Buf);
				if (UI_update == 0) break;
			}
		}
#endif

		if (page_refreshing > 30)
		{
			page_refreshing = 0;
			Get_date_variable_Id_Regular_update(pic_id);
		}

		if(Count_reg_num > 0)
		{
			Count_reg_num--;
			reg_operation(Count_reg[Count_reg_num]);
		}

		if (gWav_status > 0)	LT_PlayWav_DAC(); // WAV

#if (LT_TOUCH_FLAG == 1 || LT_TOUCH_FLAG == 2)
		gTpInfo.scan(); // Touch Point
#endif
		if (var[VAR_BLAUTO * 2 + 1] == 1)
			BackLight_control(); // backlight control

		show_gif();		 // gif
		show_Clock();	 // analog clock
		show_RTC();		 // digital clock
		scroll_text();	 // text scroll
		Display_Curve(); // curve
		show_Count();	 // time counter
		Check_Var_Count(); // timing control variable
		Check_Pointer();   //

#if LT_ENCODER
		if (gEncoderFlag)
			encoder(); // Encoder
#endif
		if(Ges_sc_flag)	slide_screen();  // unsupported
		if (Gesture_flag)	Gesture_touch(); // sliding gesture

		if (menu_flag)
		{
			sld_Menu(1);
			Auto_Slide_Menu();
		}

		Basic_touch();			// basic touch control
		Adj_touch();			// variable adjustment
		Progress_bar_sliding(); // sliding progress bar
		RingSld_touch();		// ring progress bar with touch
		slideMenu();			// slide menu
		data_input();			// data input
		Ascii_input();			// ASCII keyboard
		GBK_input();			// GBK keyboard
		VarKey_touch();			// multivariable adjustment
		pop_up_touch();			// pop-up window




#if LT_SD_UPDATE //---SDcard---
		if (SD_ud_flag)
		{
			if (!SD_detection())
				Sd_To_Flash(); // SD_pin detects a low level when an SD card is inserted.
		}
		else
		{
			if (SD_detection())
				SD_ud_flag = 1;
		}
#endif

		/****Keyboard cursor display****/
		if (Cusor_time > 60)
		{
			uint8_t buff[2],buff1[12];
			uint32_t zk_addr,color;
			Cusor_time = 0;

			if (Cusor_sw == 0)
			{
				Cusor_sw++;
				buff[0] = ' ';
				buff[1] = 0;
			}
			else
			{
				Cusor_sw = 0;
				buff[0] = '|';
				buff[1] = 0;
			}

			if (DioKb_flag == 1)
			{
				LT_ReadFlash_UI(buff1, addr_index[2] + gDio_Info[Dio_num].zk_id * 8, 4);
				zk_addr = buff1[0] + (buff1[1] << 8) + (buff1[2] << 16) + (buff1[3] << 24);

				if (gDio_Info[Dio_num].cursor_color == 0)	color = Black;
				else	color = White;

				if (Screen_DIR == 0)
				{
					if (gDio_Info[Dio_num].Alig == 0)
					{
						dx = cur_x + input_w;
						w_temp = cur_w;
					}
					else
					{
						dx = cur_x + cur_w;
						w_temp = cur_w + 2;
					}
					dy = cur_y;

					h_temp = gDio_Info[Dio_num].zk_h;
				}
				else if (Screen_DIR == 1)
				{
					dx = cur_x - gDio_Info[Dio_num].zk_h;
					if (gDio_Info[Dio_num].Alig == 0)
					{
						dy = cur_y + input_w;
						h_temp = cur_w;
					}
					else
					{
						dy = cur_y + cur_w ;
						h_temp = cur_w + 2;
					}
					w_temp = gDio_Info[Dio_num].zk_h;

				}
				else if (Screen_DIR == 2)
				{
					if (gDio_Info[Dio_num].Alig == 0)
					{
						dx = cur_x - input_w - 1;
						w_temp = cur_w;
					}
					else
					{
						dx = cur_x;
						w_temp = cur_w ;
					}
					dy = cur_y - gDio_Info[Dio_num].zk_h + 1;
					h_temp = gDio_Info[Dio_num].zk_h;
				}
				else if (Screen_DIR == 3)
				{
					if (gDio_Info[Dio_num].Alig == 0)
					{
						dy = cur_y - input_w - cur_w;
						h_temp = cur_w + 1;
					}
					else
					{
						dy = cur_y - cur_w - 2;
						h_temp = cur_w + 2;
					}
					dx = cur_x;
					w_temp = gDio_Info[Dio_num].zk_h;
				}
				LT_Print_zk_Font(4, zk_addr,
								 LAY_BUFF1, LCD_XSIZE_TFT, gDio_Info[Dio_num].zk_w, gDio_Info[Dio_num].zk_h, gDio_Info[Dio_num].Alig, color, Black, 0, 1, PICINFO[0], 0,
								 dx, dy, dx + w_temp - 1, dy + h_temp - 1,
								 0, 0, buff, 1);
			}
			else if (AioKb_flag == 1)
			{
				if (gAio_Info[Aio_num].cursor_color == 0)	color = Black;
				else	color = White;
				if (Screen_DIR == 0)
				{
					dx = cur_x + input_w;
					dy = cur_y;
					w_temp = cur_w;
					h_temp = gAio_Info[Aio_num].zk_h;
				}
				else if (Screen_DIR == 1)
				{
					dx = cur_x - gAio_Info[Aio_num].zk_h;
					dy = cur_y + input_w;
					h_temp = cur_w;
					w_temp = gAio_Info[Aio_num].zk_h;
				}
				else if (Screen_DIR == 2)
				{
					dx = cur_x - input_w -1;
					dy = cur_y - gAio_Info[Aio_num].zk_h + 1;
					w_temp = cur_w;
					h_temp = gAio_Info[Aio_num].zk_h;
				}
				else if (Screen_DIR == 3)
				{
					dy = cur_y - input_w - cur_w + 1;
					dx = cur_x;
					h_temp = cur_w;
					w_temp = gAio_Info[Aio_num].zk_h;
				}
				LT_Print_zk_Font(4, gAio_Info[Aio_num].zk_addr,
								 LAY_BUFF2, LCD_XSIZE_TFT, gAio_Info[Aio_num].zk_w, gAio_Info[Aio_num].zk_h, 3, color, White, 0, 1, PICINFO[0], 0,
								 dx, dy,  dx + w_temp - 1, dy + h_temp - 1,
								 0, 0, buff, 1);
			}
			else if (GBKioKb_flag == 1)
			{
				if (gGBKio_Info[GBKio_num].cursor_color == 0)	color = Black;
				else	color = White;
				if (Screen_DIR == 0)
				{
					dx = cur_x + input_w;
					dy = cur_y;
					w_temp = cur_w;
					h_temp = gGBKio_Info[GBKio_num].zk_h;
				}
				else if (Screen_DIR == 1)
				{
					dx = cur_x - gGBKio_Info[GBKio_num].zk_h;
					dy = cur_y + input_w;
					h_temp = cur_w;
					w_temp = gGBKio_Info[GBKio_num].zk_h;
				}
				else if (Screen_DIR == 2)
				{
					dx = cur_x - input_w - 1;
					w_temp = cur_w;
					dy = cur_y - gGBKio_Info[GBKio_num].zk_h + 1;
					h_temp = gGBKio_Info[GBKio_num].zk_h;
				}
				else if (Screen_DIR == 3)
				{
					dy = cur_y - input_w - cur_w;
					h_temp = cur_w;
					dx = cur_x;
					w_temp = gGBKio_Info[GBKio_num].zk_h;
				}
				LT_Print_zk_Font(4, gGBKio_Info[GBKio_num].zk_addr,
								 LAY_BUFF2, LCD_XSIZE_TFT, gGBKio_Info[GBKio_num].zk_w, gGBKio_Info[GBKio_num].zk_h, 3, color, White, 0, 1, PICINFO[0], 0,
								 dx, dy,  dx + w_temp - 1, dy + h_temp - 1,
								  0, 0, buff, 1);
			}
		}
	}
}
